;;;; Created on 2007-04-16 05:45:30

#|

Function w = -5x + 2y + 3z
where x, y, z = uniform(0, 10)


(setf net (list (- 10 (random 20.0)) (- 10 (random 20.0)) (- 10 (random 20.0))))

|#



(defun linear (net vals)
  (let ((result 0))
    (mapcar #'(lambda (n v)
                (setf result (+ result (* n v))))
            net vals)
    result))

(defun rand-vals nil
  (list (- 10 (random 20.0)) (- 10 (random 20.0)) (- 10 (random 20.0))))

(defun single-train (net goal vals learning)
  (mapcar #'(lambda (n v)
              (+ n (* learning (- (linear goal vals)
                                  (linear net vals))
                      v
                      0.1)))
          net vals))

             
(defun train-new-net (goal learning runs)
  (let ((net (rand-vals)))
    (dotimes (i runs)
      (setf net 
            (single-train net goal 
                          (rand-vals)
                          (* learning (/ (- runs i) runs)))))
    net))

(defun test-accuracy (net goal runs)
  (let ((SSE 0))
    (dotimes (i runs)
      (let ((temp (rand-vals)))
        (setf SSE (+ SSE (* (- (linear net temp) (linear goal temp))
                            (- (linear net temp) (linear goal temp)))))))
    (/ SSE runs)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;                 NOISE FUNCTIONS            ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun rand-normal (mean-val standard-deviation)
  (let* ((theta (random (* 2. pi)))
         (r (sqrt (* -2.0 (log (random 1.0))))))
    (+ mean-val (* standard-deviation r (cos theta)))))

(defun noise-linear (net vals)
  (+ (linear net vals) (rand-normal 0 1)))

(defun noise-single-train (net goal vals learning)
  (mapcar #'(lambda (n v)
              (+ n (* learning (- (noise-linear goal vals)
                                  (linear net vals))
                      v
                      0.1)))
          net vals))

(defun noise-train-new-net (goal learning runs)
  (let ((net (rand-vals)))
    (dotimes (i runs)
      (setf net 
            (noise-single-train net goal 
                          (rand-vals)
                          (* learning (/ (- runs i) runs)))))
    net))

(defun noise-test-accuracy (net goal runs)
  (let ((SSE 0))
    (dotimes (i runs)
      (let* ((temp (rand-vals)) (n (linear net temp)) (g (noise-linear goal temp)))
        (setf SSE (+ SSE (* (- n g)
                            (- n g))))))
    (/ SSE runs)))

#|

(setf goal '(-5 2 3))

(dotimes (k 20)
  (dotimes (j 5)
    (dotimes (i 15)
      (let ((cur (train-new-net goal (/ j 20) (expt 2 i))))
            (format t "~A:~,2F:~A:~,6F~%" k (/ j 20) (expt 2 i) (test-accuracy cur goal 1000))))))

(dotimes (k 20)
  (dotimes (j 5)
    (dotimes (i 15)
      (let ((cur (noise-train-new-net goal (/ j 20) (expt 2 i))))
            (format t "~A:~,2F:~A:~,6F~%" k (/ j 20) (expt 2 i) (noise-test-accuracy cur goal 1000))))))

(let ((k 0))
  (dotimes (j 5)
    (dotimes (i 15)
      (let ((cur (noise-train-new-net goal (/ j 20) (expt 2 i))))
            (format t "~A:~,2F:~A:~,6F~%" k (/ j 20) (expt 2 i) (noise-test-accuracy cur goal 1000))))))

|#